//! Provide the output function of debugging serial port

use crate::base::rttbase_print;
use crate::base::rttbase_print_lock;
use crate::base::rttbase_print_unlock;

use core::fmt::{self, Write};

struct StdOut;

impl fmt::Write for StdOut {
    fn write_str(&mut self, s: &str) -> fmt::Result {
        rttbase_print(s);
        Ok(())
    }
}

pub fn _print(args: fmt::Arguments) {
    rttbase_print_lock();
    StdOut.write_fmt(args).unwrap();
    rttbase_print_unlock();
}

pub fn _print_unlock(args: fmt::Arguments) {
    StdOut.write_fmt(args).unwrap();
}

#[macro_export]
macro_rules! print {
    ($($arg:tt)*) => ({
        $crate::out::_print(format_args!($($arg)*));
    });
}

macro_rules! print_unlock {
    ($($arg:tt)*) => ({
        $crate::out::_print_unlock(format_args!($($arg)*));
    });
}

#[panic_handler]
#[inline(never)]
fn panic(info: &core::panic::PanicInfo) -> ! {
    print_unlock!("{:}", info);
    loop{}
}